package com.ply.controller;

import com.ply.entity.pojo.Project;
import com.ply.entity.pojo.User;
import com.ply.entity.pojo.VoteOption;
import com.ply.entity.vo.ConsumerMsg;
import com.ply.entity.vo.ProjectAndOption;
import com.ply.entity.vo.ProjectOption;
import com.ply.entity.vo.Result;
import com.ply.filter.UserUtils;
import com.ply.mapper.ProjectMapper;
import com.ply.mapper.UserMapper;
import com.ply.service.impl.LevelServiceImpl;
import com.ply.service.impl.UserServiceImpl;
import com.ply.utils.RuleUtils;
import com.ply.utils.TokenUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * @author XiaoPan
 * date: 2022/1/7 17:03
 * <p>
 * action: 用户控制层
 */


@Slf4j
@RestController
@RequestMapping("/")
@CrossOrigin
public class UserController {
    private final LevelServiceImpl levelService;
    private final UserServiceImpl userService;
    private final UserMapper userMapper;

    private final ProjectMapper projectMapper;

    public UserController(LevelServiceImpl levelService, UserServiceImpl userService, UserMapper userMapper,ProjectMapper projectMapper) {
        this.levelService = levelService;
        this.userService = userService;
        this.userMapper = userMapper;
        this.projectMapper = projectMapper;
    }


    @PostMapping("/login.do")
    public Result<?> login(@RequestBody User user,
                           HttpServletResponse response) {
        //获取用户名 密码
        String name = user.getName();
        String pwd = user.getPasswd();

        log.info("用户:{}尝试登陆 密码:{}", name,pwd);

        //将Token 响应头 暴露出来
        response.setHeader("Access-Control-Expose-Headers", "Token");

        //判断 用户名 密码 传进来的时候 是否为空
        if (name == null || pwd == null || "".equals(name) || "".equals(pwd)) {
            return Result.fail("用户名或密码为空");
        }

        //登录判断
        Result<?> result = userService.login(name, pwd);

        //登陆成功 就将token 加入响应头
        if (result.isTrue()) {
            User date = (User) result.getDate();
            log.info("用户:{}登陆成功", date.getName());
            String type = "用户";
            //生成新的token
            String newToken = TokenUtils.toToken(date.getId(), type);
            System.out.println(newToken);
            //设置响应头
            response.setHeader("Token", newToken);
            return result;
        }
        return Result.fail("登陆失败");
    }


    @GetMapping("/user/queryUserInfo.do")
    public Result<?> getUserInfo(){
        Integer userId = UserUtils.getUserId();

        User user = userMapper.queryUserByUserId(userId);

        Result ok = Result.ok();
        ok.setDate(user);
        return ok;
    }


    @RequestMapping("/register.do")
    public Result<?> register(@RequestParam("name") String name,
                              @RequestParam("pwd") String pwd) {
        //判断 用户名和密码 是否为空
        if (name == null || pwd == null || "".equals(name) || "".equals(pwd)) {
            return Result.fail("用户名或密码为空");
        }

        //判断用户名是否非法
        if (!RuleUtils.userName(name)) {
            return Result.fail("用户名非法");
        }

        User user = new User(name, pwd);
        return userService.register(user);
    }

    /**
     * 创建投票
     * 前端 应该 给 一个项目
     * 必须: 用户名 name, 项目 开始时间 startAt
     * 默认 每个每天可以投的票 voteNumEvery: 2
     */

    @RequestMapping("user/createVote")
    public Result<?> createVote(@RequestBody ProjectAndOption projectAndOption) {

        Integer userId = UserUtils.getUserId();

        projectAndOption.getProject().setUserId(userId);

        log.info("在createVote中 projectAndOption的值 {}", projectAndOption);

        Result<?> result = userService.sendVote(projectAndOption);

        if (result.isTrue()) {
            result.setMsg("创建项目   " + projectAndOption.getProject().getName() + "    成功");
        }

        return result;
//        return userService.sendVote(userId, project);
    }

    /**
     * 充值 接口
     *
     * @param map 可以接收 amount 是 double 格式的
     */
    @PostMapping("/user/recharge")
    public Result<?> recharge(@RequestBody Map<String, Object> map,
                              HttpServletRequest request) {
        // 需要判空 异常的 还有类型异常的 毕竟 map
        int userId = (int) request.getAttribute("userId");
        Object object = map.get("amount");

        //判断为空 防止空指针
        if (object == null) {
            return Result.fail("没有充值金额");
        }

        // 充值的金额 合不合法 是不是一个 数值
        if (!RuleUtils.amountRule(object)) {
            log.info("数据为:{}",object);
            return Result.fail("数据格式不对");
        }
        double amount = Double.parseDouble(object.toString());

         //if (object instanceof Number) {
         //amount = ((Number) object).doubleValue();
         //}

        Result<?> recharge = userService.recharge(userId, amount);

        if (recharge.isTrue()) {
            recharge.setMsg("用户:" + userId + "   充值" + amount + "成功");
        }
        return recharge;
    }


    /**
     * 购买 发起投票次数接口 接口
     * 需要接收 用户id  和几次
     */
    @GetMapping("/user/queryAmountForCount")
    public Result<?> queryAmountForCount(HttpServletRequest request,
                                      Integer count) {

        log.info("查询 购买 项目发起的 次数 多少钱 :{}", count);
        String dayStr = count.toString();

        //判断 传进来的参数 格式 是正整数
        if (!RuleUtils.positiveIntegerRule(dayStr)) {
            return Result.fail("count输入参数格式不对");
        }

        //获取 用户id
        int userId = (int) request.getAttribute("userId");
        // TODO 通过用户id 查询到 用户的信息 按道理不可以这样的(直接越过service层 到Mapper 层 这样可以吗)
        User user = userMapper.queryUserByUserId(userId);

        double amount = levelService.buyVoteNumMoney(user.getLevelId(), count);
        return Result.ok("购买发起投票数" + count + "天的金额是:" + amount, amount);
    }

    /**
     * 查询 项目 延长 时间 的金额
     * 参数 ： day  几天  用户id（用用于 查询等级  对应的 金额）    参数 格式 最大 三位数
     *
     * @param day     延长时间的金额
     */
    @GetMapping("/user/queryAmountForDay")
    public Result<?> queryAmountForDay(HttpServletRequest request,
                                    Integer day) {

        log.info("查询 项目 延长 时间 的天数 :{}", day);

        String dayStr = day.toString();

        if (!RuleUtils.positiveIntegerRule(dayStr)) {
            return Result.fail("day输入参数格式不对");
        }

        int userId = (int) request.getAttribute("userId");
        //获取 用户等级id
        User user = userMapper.queryUserByUserId(userId);
        double amount = levelService.buyDayMoney(user.getLevelId(), day);
        return Result.ok("购买延长项目时间" + day + "天的金额是:" + amount, amount);
    }


    /**
     * 购买的次数 接口
     * 需要接收项目 id   购买的天数
     *
     */
    @PostMapping("/user/shoppingCount")
    public Result<?> shoppingCount(HttpServletRequest request,
                                @RequestBody Map<String, Integer> map) {

        //获取 购买的次数
        Integer count = map.get("count");

        // todo 需要测试(不知道可不可以传 不是int 参数)  这里不需要判断格式  是因为 前端传进来的
        if (count == null) {
            return Result.fail("购买失败");
        }

        int userId = (int) request.getAttribute("userId");
        User user = userMapper.queryUserByUserId(userId);
        double amount = levelService.buyVoteNumMoney(user.getLevelId(), count);
        return userService.shopping(userId, amount, ConsumerMsg.BUY_VOTE, count, null);
    }

    /**
     * 购买的day 接口
     * 需要接收项目 id   购买的天数    那个项目id
     *
     */
    @PostMapping("/user/shoppingDay")
    public Result<?> shopping(HttpServletRequest request,
                           @RequestBody Map<String, Integer> map) {

        Integer count = map.get("count");
        Integer projectId = map.get("projectId");

        // todo 需要测试(不知道可不可以传 不是int 参数)  这里不需要判断格式  是因为 前端传进来的
        if (count == null || projectId == null) {
            return Result.fail("参数异常");
        }

        int userId = (int) request.getAttribute("userId");
        User user = userMapper.queryUserByUserId(userId);
        System.out.println(user.getLevelId());
        double amount = levelService.buyVoteNumMoney(user.getLevelId(), count);
        log.info("count:{}", count);
        return userService.shopping(userId, amount, ConsumerMsg.BUY_VOTE_OUT_TIME, count, projectId);
    }


    /**
     * 查询 用户 的 创建的所有项目  的信息
     *
     * @param page    页数
     * @param pageNum 每页的个数
     * @return 成功还是失败
     */

    @GetMapping("/user/getMyProject")
    public Result<?> getMyProject(Integer page, Integer pageNum,
                               HttpServletRequest request) {

        if (page == null || pageNum == null) {
            return Result.fail("页数出错");
        }

        if (page <= 0 || pageNum <= 0) {
            return Result.fail("页数出错");
        }

        Integer userId = (Integer) request.getAttribute("userId");

        return userService.queryMyProjectNoVoteOp(page, pageNum, userId);
    }


    /**
     * 查询 我创建的 的一个项目 的 具体信息
     */

    @GetMapping("/user/getMyOneProject")
    public Result<?> getMyOneProject(Integer projectId, HttpServletRequest request) {


        if (projectId < 0) {
            return Result.fail("projectId参数错误");
        }

        Integer userId = (Integer) request.getAttribute("userId");

        Result<?> result = userService.queryMyProject(userId);


        List<ProjectOption> date = (List<ProjectOption>) result.getDate();

        for (ProjectOption projectOption : date) {

            Integer id = projectOption.getId();

            System.out.println(id);

            if (Objects.equals(id, projectId)) {
                return Result.ok(projectOption);
            }

            System.out.println(projectOption);
        }

        return Result.ok("查询失败");
    }


    @PostMapping("user/createVoteOnTitle")
    public Result<?> createVoteOnTitle(@RequestBody Project project) {

        Integer userId = UserUtils.getUserId();

        project.setUserId(userId);
        log.info("createVoteOnTitle project {}", project);

        Result<?> result = userService.sendVote(project);

        if (result.isTrue()) {
            result.setMsg("创建项目   " + project.getName() + "    成功");
        }

        return result;
//        return userService.sendVote(userId, project);
    }


    @PostMapping("user/addVoteOption")
    public Result<?> addVoteOption(@RequestBody VoteOption voteOption) {

        Integer userId = UserUtils.getUserId();

        int projectId = voteOption.getCreatVoteId();

        //判断 此用户 是否 有 此项目
        Integer integer = projectMapper.selectProjectByUserIdAndProId(projectId, userId);

        if (integer ==0 ){
            return Result.fail("该项目 不属于 你");
        }


        log.info("createVoteOnTitle project {}", voteOption);

        Result<?> result = userService.addVoteOption(projectId,voteOption);

        if (result.isTrue()) {
            result.setMsg("增加选项   " + voteOption.getName() + "    成功");
        }

        return result;
    }









}






